<!--
  * 菜单 表单弹窗
  *
  * @Author:    zhoujk
  * @Date:      2025-02-05 16:44
-->
<template>
  <a-drawer
    :body-style="{ paddingBottom: '80px' }"
    :maskClosable="true"
    :title="form.id ? '编辑' : '添加'"
    :open="visible"
    :width="600"
    @close="onClose"
  >
    <a-form ref="formRef" :labelCol="{ span: labelColSpan }" :labelWrap="true" :model="form" :rules="rules">
      <a-form-item label="菜单类型" name="type">
        <a-radio-group v-model:value="form.type" button-style="solid">
          <a-radio-button v-for="item in ZZB_MENU_TYPE_ENUM" :key="item.value" :value="item.value">
            {{ item.desc }}
          </a-radio-button>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="菜单来源类型" name="sourceType">
        <a-radio-group v-model:value="form.sourceType" button-style="solid" :options="MENU_SOURCE_TYPE" />
      </a-form-item>
      <a-form-item :label="form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_CATALOG.value ? '上级目录' : '上级菜单'">
        <MenuTreeSelect ref="parentMenuTreeSelect" v-model:value="form.fMenuId" />
      </a-form-item>
      <a-form-item label="英文名称" name="enName" help="用于前端国际化使用">
        <a-input v-model:value="form.enName" placeholder="请输入英文名称" />
      </a-form-item>
      <a-form-item label="固定菜单" name="fixedFlag">
        <a-switch v-model:checked="form.fixedFlag" checked-children="固定" un-checked-children="不固定" />
      </a-form-item>
      <a-form-item label="显示状态" name="visibleFlag">
        <a-switch v-model:checked="form.visibleFlag" checked-children="显示" un-checked-children="不显示" />
      </a-form-item>
      <!--      目录 菜单 start   -->
      <template v-if="form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_CATALOG.value || form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_MENU.value">
        <a-form-item label="菜单名称" name="name">
          <a-input v-model:value="form.name" placeholder="请输入菜单名称" />
        </a-form-item>

        <a-form-item label="菜单图标" name="icon">
          <IconSelect @updateIcon="selectIcon">
            <template #iconSelect>
              <a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px" />
              <component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px" />
            </template>
          </IconSelect>
        </a-form-item>
        <a-form-item v-if="form.type !== ZZB_MENU_TYPE_ENUM.MENU_TYPE_POINTS.value" label="路由地址" name="path">
          <a-input v-model:value="form.path" placeholder="请输入路由地址" />
        </a-form-item>
        <template v-if="form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_MENU.value">
          <a-form-item v-if="form.frameFlag" label="外链地址" name="frameUrl">
            <a-input v-model:value="form.frameUrl" placeholder="请输入外链地址" />
          </a-form-item>
          <a-form-item v-else label="组件地址" name="component" help="比如 商品列表：/business/erp/goods/goods-list.vue">
            <a-input v-model:value="form.component" placeholder="请输入组件地址 默认带有开头/@/views" />
          </a-form-item>
        </template>
      </template>
      <!--      目录 菜单 end   -->
      <!--      按钮 start   -->
      <template v-if="form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_POINTS.value">
        <a-form-item label="权限" name="permission" help="用于前端按钮等功能的展示和隐藏，搭配v-privilege使用">
          <a-input v-model:value="form.permission" placeholder="请输入权限" />
        </a-form-item>
        <!--<a-form-item label="权限类型" name="permsType">-->
        <!--  <a-radio-group v-model:value="form.permsType">-->
        <!--    <a-radio v-for="item in MENU_PERMS_TYPE_ENUM" :key="item.value" :value="item.value">-->
        <!--      {{ item.desc }}-->
        <!--    </a-radio>-->
        <!--  </a-radio-group>-->
        <!--</a-form-item>-->
      </template>
      <template v-if="form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_POINTS.value">
        <a-form-item label="操作类型" name="operType">
          <a-radio-group v-model:value="form.operType" button-style="solid">
            <a-radio-button v-for="item in ZZB_MENU_OPER_TYPE_ENUM" :key="item.value" :value="item.value">
              {{ item.desc }}
            </a-radio-button>
          </a-radio-group>
        </a-form-item>
        <a-form-item label="功能点名称" name="name">
          <a-input v-model:value="form.name" placeholder="请输入功能点名称" />
        </a-form-item>
        <!--<a-form-item label="权限类型" name="permsType">-->
        <!--  <a-radio-group v-model:value="form.permsType">-->
        <!--    <a-radio v-for="item in MENU_PERMS_TYPE_ENUM" :key="item.value" :value="item.value">-->
        <!--      {{ item.desc }}-->
        <!--    </a-radio>-->
        <!--  </a-radio-group>-->
        <!--</a-form-item>-->
      </template>
      <!--      按钮 end   -->
      <a-form-item label="排序" name="num" help="值越小越靠前">
        <a-input-number v-model:value="form.num" :min="0" placeholder="请输入排序" style="width: 100px" />
      </a-form-item>
    </a-form>
    <div class="footer">
      <a-button style="margin-right: 8px" @click="onClose">取消</a-button>
      <a-button style="margin-right: 8px" type="primary" @click="onSubmit(false)">提交</a-button>
      <a-button v-if="!form.id" type="primary" @click="onSubmit(true)">提交并添加下一个</a-button>
    </div>
  </a-drawer>
</template>
<script setup>
  import { menuMerchantApi } from '/@/api/system/b-merchant/menu-api.js'
  import { message } from 'ant-design-vue'
  import _ from 'lodash'
  import { computed, inject, nextTick, reactive, ref } from 'vue'
  import MenuTreeSelect from './menu-tree-select.vue'
  import { menuApi } from '/src/api/system/b-operation/menu-api'
  import IconSelect from '/src/components/framework/icon-select/index.vue'
  import { MENU_DEFAULT_PARENT_ID, MENU_PERMS_TYPE_ENUM, ZZB_MENU_OPER_TYPE_ENUM, ZZB_MENU_TYPE_ENUM } from '/@/constants/system/menu-const'
  import { smartSentry } from '/src/lib/smart-sentry'
  import { SmartLoading } from '/src/components/framework/smart-loading'
  import { ZZB_ENABLE_STATUS_ENUM, ZZB_USER_TYPE_ENUM } from '/src/constants/system/system-const.js'
  import { MENU_SOURCE_TYPE } from '/@/constants/dict'

  // ----------------------- 以下是字段定义 emits props ------------------------
  // emit
  const emit = defineEmits(['reloadList'])

  const selectedUserType = inject('selectedUserType')

  // ----------------------- 展开、隐藏编辑窗口 ------------------------

  // 是否展示抽屉
  const visible = ref(false)

  const labelColSpan = computed(() => {
    if (form.type === ZZB_MENU_TYPE_ENUM.MENU_TYPE_POINTS.value) {
      return 6
    }
    return 4
  })

  const contextMenuTreeSelect = ref()
  const parentMenuTreeSelect = ref()

  //展开编辑窗口
  async function showDrawer(rowData) {
    console.log(rowData)
    Object.assign(form, formDefault)
    if (rowData && !_.isEmpty(rowData)) {
      Object.assign(form, rowData)
      if (form.fMenuId === MENU_DEFAULT_PARENT_ID) {
        form.fMenuId = null
      }
    }

    visible.value = true
    refreshParentAndContext()
  }

  function refreshParentAndContext() {
    nextTick(() => {
      if (contextMenuTreeSelect.value) {
        contextMenuTreeSelect.value.queryMenuTree()
      }
      if (parentMenuTreeSelect.value) {
        parentMenuTreeSelect.value.queryMenuTree()
      }
    })
  }

  // 隐藏窗口
  function onClose() {
    Object.assign(form, formDefault)
    formRef.value.resetFields()
    visible.value = false
  }

  // ----------------------- form表单相关操作 ------------------------

  const formRef = ref()
  const formDefault = {
    id: undefined,
    name: undefined,
    userType: ZZB_USER_TYPE_ENUM.USER_TYPE_PLATFORM.value,
    type: ZZB_MENU_TYPE_ENUM.MENU_TYPE_CATALOG.value,
    sourceType: 1,
    icon: undefined,
    fMenuId: undefined,
    path: undefined,
    permsType: MENU_PERMS_TYPE_ENUM.SA_TOKEN.value,
    enName: undefined,
    permission: undefined,
    num: 0,
    status: ZZB_ENABLE_STATUS_ENUM.DISABLE_STATUS.value,
    cacheFlag: true,
    component: undefined,
    contextId: undefined,
    frameFlag: false,
    frameUrl: undefined,
    fixedFlag: false,
    visibleFlag: true,
    operType: ZZB_MENU_OPER_TYPE_ENUM.MENU_OPER_TYPE_INSERT.value,
  }
  let form = reactive({ ...formDefault })

  function continueResetForm() {
    refreshParentAndContext()
    const type = form.type
    const fMenuId = form.fMenuId
    const permission = form.permission
    Object.assign(form, formDefault)
    formRef.value.resetFields()
    form.type = type
    form.fMenuId = fMenuId
    // 移除最后一个：后面的内容
    if (permission && permission.lastIndexOf(':')) {
      form.permission = permission.substring(0, permission.lastIndexOf(':') + 1)
    }
  }

  const rules = {
    type: [{ required: true, message: '菜单类型不能为空' }],
    sourceType: [{ required: true, message: '菜单来源类型不能为空' }],
    component: [
      { required: true, message: '组件地址不能为空' },
      { max: 255, message: '组件地址不能大于255个字符', trigger: 'blur' },
    ],
    enName: [
      { required: true, message: '英文名称不能为空' },
      { max: 255, message: '英文名称不能大于255个字符', trigger: 'blur' },
    ],
    permission: [{ required: true, message: '权限不能为空' }],
    name: [
      { required: true, message: '菜单名称不能为空' },
      { max: 20, message: '菜单名称不能大于20个字符', trigger: 'blur' },
    ],
    path: [
      { required: true, message: '路由地址不能为空' },
      { max: 100, message: '路由地址不能大于100个字符', trigger: 'blur' },
    ],
  }

  function validateForm(formRef) {
    return new Promise((resolve) => {
      formRef
        .validate()
        .then(() => {
          resolve(true)
        })
        .catch(() => {
          resolve(false)
        })
    })
  }

  const onSubmit = async (continueFlag) => {
    let validateFormRes = await validateForm(formRef.value)
    if (!validateFormRes) {
      message.error('参数验证错误，请仔细填写表单数据!')
      return
    }
    SmartLoading.show()
    try {
      let params = _.cloneDeep(form)
      // 若无父级ID 默认设置为0000000000000
      if (!params.fMenuId) {
        params.fMenuId = MENU_DEFAULT_PARENT_ID
      }
      if (!params.id) {
        params.userType = selectedUserType.value
      }
      if (params.id) {
        if (ZZB_USER_TYPE_ENUM.USER_TYPE_MERCHANT.value === selectedUserType.value) {
          await menuMerchantApi.update(params)
        } else {
          await menuApi.update(params)
        }
      } else {
        if (ZZB_USER_TYPE_ENUM.USER_TYPE_MERCHANT.value === selectedUserType.value) {
          await menuMerchantApi.insert(params)
        } else {
          await menuApi.insert(params)
        }
      }
      message.success(`${params.id ? '修改' : '添加'}成功`)
      if (continueFlag) {
        continueResetForm()
      } else {
        onClose()
      }
      emit('reloadList')
    } catch (error) {
      smartSentry.captureError(error)
    } finally {
      SmartLoading.hide()
    }
  }

  function selectIcon(icon) {
    form.icon = icon
  }

  // ----------------------- 以下是暴露的方法内容 ------------------------
  defineExpose({
    showDrawer,
  })
</script>
<style lang="less" scoped>
  .footer {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 100%;
    border-top: 1px solid #e9e9e9;
    padding: 10px 16px;
    background: #fff;
    text-align: left;
    z-index: 1;
  }
</style>
